Skip to content

Optimize Buffer.fill() to avoid intermediate object creation - #1376

Merged
leofang merged 2 commits into
NVIDIA:mainfrom
Andy-Jost:buffer-fill-redesign
Dec 16, 2025
Merged

Optimize Buffer.fill() to avoid intermediate object creation#1376
leofang merged 2 commits into
NVIDIA:mainfrom
Andy-Jost:buffer-fill-redesign

Conversation

@Andy-Jost

Copy link
Copy Markdown
Contributor

Summary

  • Use Cython typed parameters and C buffer API to eliminate Python object creation overhead in Buffer.fill()
  • int path: uint8_t parameter for automatic overflow checking
  • bytes path: direct char* pointer access
  • general buffer path: PyObject_GetBuffer for direct void* access

Closes #1375

Test Plan

  • All 99 test_buffer_fill tests pass

Use Cython typed parameters and C buffer API to eliminate overhead:
- int path: uint8_t parameter for automatic overflow checking
- bytes path: direct char* pointer access
- general buffer path: PyObject_GetBuffer for direct void* access
@Andy-Jost Andy-Jost added this to the cuda.core beta 10 milestone Dec 16, 2025
@Andy-Jost Andy-Jost added enhancement Any code-related improvements cuda.core Everything related to the cuda.core module labels Dec 16, 2025
@Andy-Jost Andy-Jost self-assigned this Dec 16, 2025
@Andy-Jost
Andy-Jost requested a review from leofang December 16, 2025 00:59
@copy-pr-bot

copy-pr-bot Bot commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@Andy-Jost
Andy-Jost requested review from rparolin and rwgk December 16, 2025 00:59
@Andy-Jost

Copy link
Copy Markdown
Contributor Author

/ok to test 415469e

@Andy-Jost

Copy link
Copy Markdown
Contributor Author

@kkraus14 I think this implementation follows the approach you outlined.

@Andy-Jost
Andy-Jost requested a review from kkraus14 December 16, 2025 01:03
@Andy-Jost Andy-Jost added the P0 High priority - Must do! label Dec 16, 2025
@github-actions

This comment has been minimized.

@Andy-Jost

Copy link
Copy Markdown
Contributor Author

/ok to test 355be58

@kkraus14

Copy link
Copy Markdown
Collaborator

LGTM, this was basically exactly what I had in mind except your implementation was more elegantly using Cython instead of jumping straight down to the CPython API 😄

@leofang leofang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM too! Left a few nits. Nothing is critical.

Comment on lines +385 to +387
cdef inline void Buffer_fill_uint8(Buffer self, uint8_t value, cydriver.CUstream s):
with nogil:
HANDLE_RETURN(cydriver.cuMemsetD8Async(<cydriver.CUdeviceptr>self._ptr, value, self._size, s))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we want the exception clause except* since HANDLE_RETURN can raise, but we don't want Cython to warn, so with Cython 3 we general want to avoid using void as the return type and use this instead:

Suggested change
cdef inline void Buffer_fill_uint8(Buffer self, uint8_t value, cydriver.CUstream s):
with nogil:
HANDLE_RETURN(cydriver.cuMemsetD8Async(<cydriver.CUdeviceptr>self._ptr, value, self._size, s))
cdef inline int Buffer_fill_uint8(Buffer self, uint8_t value, cydriver.CUstream s) except?-1:
with nogil:
HANDLE_RETURN(cydriver.cuMemsetD8Async(<cydriver.CUdeviceptr>self._ptr, value, self._size, s))
return 0

Comment on lines +390 to +392
cdef inline void Buffer_fill_from_ptr(
Buffer self, const char* ptr, size_t width, cydriver.CUstream s
) except *:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Suggested change
cdef inline void Buffer_fill_from_ptr(
Buffer self, const char* ptr, size_t width, cydriver.CUstream s
) except *:
cdef inline int Buffer_fill_from_ptr(
Buffer self, const char* ptr, size_t width, cydriver.CUstream s
) except?-1:

HANDLE_RETURN(cydriver.cuMemsetD32Async(
<cydriver.CUdeviceptr>self._ptr, (<uint32_t*>ptr)[0], buffer_size // 4, s))
else:
raise ValueError(f"value must be 1, 2, or 4 bytes, got {width}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise ValueError(f"value must be 1, 2, or 4 bytes, got {width}")
raise ValueError(f"value must be 1, 2, or 4 bytes, got {width}")
return 0

@leofang
leofang merged commit 83eaec1 into NVIDIA:main Dec 16, 2025
156 of 157 checks passed
@github-actions

Copy link
Copy Markdown
Doc Preview CI
Preview removed because the pull request was closed or merged.

@Andy-Jost
Andy-Jost deleted the buffer-fill-redesign branch January 14, 2026 01:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cuda.core Everything related to the cuda.core module enhancement Any code-related improvements P0 High priority - Must do!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEA]: Reduce Python object creation in Buffer.fill

3 participants